/**
 * XHR.js
 *
 * Copyright, Moxiecode Systems AB
 * Released under LGPL License.
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

/**
 * This class enables you to send XMLHTTPRequests cross browser.
 * @class tinymce.util.XHR
 * @static
 * @example
 * // Sends a low level Ajax request
 * tinymce.util.XHR.send({
 *    url : 'someurl',
 *    success : function(text) {
 *       console.debug(text);
 *    }
 * });
 */
tinymce.create('static tinymce.util.XHR', {
	/**
	 * Sends a XMLHTTPRequest.
	 * Consult the Wiki for details on what settings this method takes.
	 *
	 * @method send
	 * @param {Object} o Object will target URL, callbacks and other info needed to make the request.
	 */
	send : function(o) {
		var x, t, w = window, c = 0;

		function ready() {
			if (!o.async || x.readyState == 4 || c++ > 10000) {
				if (o.success && c < 10000 && x.status == 200)
					o.success.call(o.success_scope, '' + x.responseText, x, o);
				else if (o.error)
					o.error.call(o.error_scope, c > 10000 ? 'TIMED_OUT' : 'GENERAL', x, o);

				x = null;
			} else
				w.setTimeout(ready, 10);
		};

		// Default settings
		o.scope = o.scope || this;
		o.success_scope = o.success_scope || o.scope;
		o.error_scope = o.error_scope || o.scope;
		o.async = o.async === false ? false : true;
		o.data = o.data || '';

		function get(s) {
			x = 0;

			try {
				x = new ActiveXObject(s);
			} catch (ex) {
			}

			return x;
		};

		x = w.XMLHttpRequest ? new XMLHttpRequest() : get('Microsoft.XMLHTTP') || get('Msxml2.XMLHTTP');

		if (x) {
			if (x.overrideMimeType)
				x.overrideMimeType(o.content_type);

			x.open(o.type || (o.data ? 'POST' : 'GET'), o.url, o.async);

			if (o.content_type)
				x.setRequestHeader('Content-Type', o.content_type);

			x.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

			x.send(o.data);

			// Syncronous request
			if (!o.async)
				return ready();

			// Wait for response, onReadyStateChange can not be used since it leaks memory in IE
			t = w.setTimeout(ready, 10);
		}
	}
});
